/*
 * Part of the ACID Project
 * Developed in 2011 by Morgan Taschuk
 */
package acid.plugin.expression.allpairs;

import acid.plugin.expression.ReadExpressionData;
import acid.plugin.gui.ConfigurationOptions;
import acid.spring.db.GeneAlias;
import cytoscape.CyNode;
import cytoscape.Cytoscape;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 *
 * @author morgan
 */
public class AllPairsExpression {

    private ReadExpressionData red = null;
    private Map<String, Set<GeneAlias>> cyIdToGeneAlias;
    public double mean = 0;
    public long n = 1;
    private double maxPVal, minFoldChange;

    public AllPairsExpression() {
    }

    public String doStuff(double maxPVal, double minFoldChange) {
        this.maxPVal= maxPVal;
        this.minFoldChange = minFoldChange;
        System.out.println("Starting...");
        initialize();
        String filename = "allpairsexpression_" + System.currentTimeMillis() + ".out";
        try {
            PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter(filename)), true);

            ArrayList<CyNode> allnodes = new ArrayList<CyNode>(Cytoscape.getCyNodesList());
            int numNodes = allnodes.size();
            //long nMax = //factorial(numNodes) / (2 * factorial(numNodes - 2));

            for (int i = 0; i < numNodes - 1; i++) {
                for (int j = i + 1; j < numNodes; j++) {
                    CyNode s = allnodes.get(i);
                    CyNode t = allnodes.get(j);

                    Set<GeneAlias> sGA = cyIdToGeneAlias.get(s.getIdentifier());
                    Set<GeneAlias> tGA = cyIdToGeneAlias.get(t.getIdentifier());
                    if (sGA != null && tGA != null) {
                        double sim = red.getEuclideanExpressionSimilarity(sGA, tGA, maxPVal, minFoldChange);
                        double sim2 = red.getPearsonExpressionSimilarity(tGA, tGA, maxPVal, minFoldChange);
                        double sim3 = sim + sim2;
                        out.print(s.getIdentifier() + "\t" + t.getIdentifier() + "\t");
                        if (Double.isNaN(sim)) {
                            sim=0;
                        }
                        if (Double.isNaN(sim2)) {
                            sim2=0;
                        }
                        if (Double.isNaN(sim3)) {
                            sim3=sim+sim2;
                        }
                        out.println(sim+"\t"+sim2+"\t"+sim3);
                        n++;

                    }
                }
                System.out.println(n + " comparisons, " + (i + 1) + "/" + numNodes + " done");
            }
            System.out.println("\n Average: " + mean);
            out.flush();
            out.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return filename;

    }

    private void initialize() {
        if (red == null) {
            red = new ReadExpressionData(ConfigurationOptions.ALIAS_ATT, maxPVal, minFoldChange);
            cyIdToGeneAlias = red.getGeneAliases();
        }
    }
}
